/*
 * @Author       : Wei.Studio
 * @Date         : 2023-01-28 18:47:14
 * @LastEditors  : Wei.Studio awokezhou@gmail.com
 * @LastEditTime : 2024-04-13 14:36:29
 * @FilePath     : \qesf\include\qe_log.h
 * @Description  : 
 * 
 * Copyright (c) 2022 by Wei.Studio, All Rights Reserved. 
 */



#ifndef __QE_LOG_H__
#define __QE_LOG_H__



#include "qe_def.h"
#include "qe_buffer.h"



#define QELOG_DOMAIN_INITCALL		"qe-initcall"
#define QELOG_DOMAIN_HEX			"qe-hex"
#define QELOG_DOMAIN_BIT			"qe-bit"
#define QELOG_DOMAIN_HASH			"qe-hash"
#define QELOG_DOMAIN_DBGCTRL		"qe-dbgctrl"
#define QELOG_DOMAIN_PACK			"qe-pack"
#define QELOG_DOMAIN_BUFFER			"qe-buff"
#define QELOG_DOMAIN_SHELL			"qe-shell"
#define QELOG_DOMAIN_SDTRACE		"qe-sdtrace"
#define QELOG_DOMAIN_ROLLFILE		"qe-rfile"
#define QELOG_DOMAIN_ARGPARSE		"qe-argp"
#define QELOG_DOMAIN_GRAPH			"qe-graph"

#define QELOG_DOMAIN_DM				"qe-dm"
#define QELOG_DOMAIN_SERIAL			"qe-serial"
#define QELOG_DOMAIN_IIC			"qe-iic"
#define QELOG_DOMAIN_SPI			"qe-spi"
#define QELOG_DOMAIN_SPIF			"qe-spif"
#define QELOG_DOMAIN_GPIO			"qe-gpio"
#define QELOG_DOMAIN_TIMER			"qe-timer"
#define QELOG_DOMAIN_INTC			"qe-intc"
#define QELOG_DOMAIN_EARLYCON		"qe-earlycon"



#define _QELOG_DOMAIN_NAME_STR(num) #num
#define QELOG_DOMAIN_NAME_STR(num) _QELOG_DOMAIN_NAME_STR(num)


/**
 * Log Color define
 */
#define QELOG_COLOR_RESET			"\033[0m"
#define QELOG_COLOR_RED				"\033[31m"
#define QELOG_COLOR_GREEN			"\033[32m"
#define QELOG_COLOR_YELLOW			"\033[33m"
#define QELOG_COLOR_BLUE			"\033[34m"
#define QELOG_COLOR_PINK			"\033[35m"
#define QELOG_COLOR_CYAN			"\033[36m"
#define QELOG_COLOR_WHITE			"\033[37m"
#define QELOG_COLOR_LIGHT_RED		"\033[91m"
#define QELOG_COLOR_LIGHT_GREEN		"\033[92m"
#define QELOG_COLOR_LIGHT_YELLOW	"\033[93m"
#define QELOG_COLOR_LIGHT_BLUE		"\033[94m"
#define QELOG_COLOR_LIGHT_PINK		"\033[95m"
#define QELOG_COLOR_LIGHT_CYAN		"\033[96m"
#define QELOG_COLOR_LIGHT_WHITE		"\033[97m"

/**
 * Log Level define
 */
typedef enum {
	QELOG_DEBUG = 0,
	QELOG_INFO,
	QELOG_NOTICE,
	QELOG_WARNING,
	QELOG_CRITICAL,
	QELOG_ERROR,
	QELOG_FATAL,
	QELOG_DISABLE,
	QELOG_SIZEOF,
} qelog_level_e;



typedef void (*qelog_handler_t)(const char *domain_name, qelog_level_e level, 
	const char *file, const char *func, int line, const char *message);

typedef void (*qelog_output_t)(const char *message);


/**
 * @brief Log flags, define some features
 */
typedef enum {

	/* time format, only one select */
	QELOG_HMS    = 1 << 0,		/* Log format with H:M:S like:[10:15:23] xxx */
	QELOG_DATE   = 1 << 1,		/* Log format with Y/M/D H:M:S like:[2000/01/01 10:15:23] xxx */
	QELOG_PTS    = 1 << 2,		/* Log format with timestamp(us) [1693923361000000] xxx */

	/* format */
	QELOG_DM     = 1 << 3,		/* Log format with domain name */
	QELOG_DNL	 = 1 << 4,		/* Log domain name limit */
	QELOG_LV     = 1 << 5,		/* Log format with level key */
	QELOG_FILE   = 1 << 6,		/* Log format with file name */
	QELOG_FUNC   = 1 << 7,		/* Log format with function name */
	QELOG_LINE   = 1 << 8,		/* Log format with line number */
	QELOG_PID    = 1 << 9,		/* Log format with PID */ 
	QELOG_CL     = 1 << 10,		/* Log format with color */
	
	/* handler */
	QELOG_RECUR  = 1 << 11,		/* Log use a stack buffer to do format */

	/* output */
	QELOG_RB     = 1 << 16,		/* Log save to ringbuffer */
#ifdef CONFIG_LOG_ARCHIVE
	QELOG_AR     = 1 << 17,		/* Log archive */
#endif
} qelog_flags_e;

void qelog(const char *name, qelog_level_e level,
    const char *file, const char *func, int line, const char *fmt, ...);

qe_ret 
qelog_init(qelog_level_e level, qe_u32 flags);

void 
qelog_set_flags(qe_u32 flags);

qe_u32 
qelog_get_flags(void);

qe_ret 
qelog_set_level(qelog_level_e level);

qelog_level_e 
qelog_get_level(void);

const char *
qelog_get_level_str(qelog_level_e level);

void 
qelog_set_default_handler(qelog_handler_t handler);

qe_ret 
qelog_set_buffer(void *buf, qe_u32 size);
qe_ringbuffer *
qelog_get_buffer(void);

#if defined(CONFIG_LOG_ARCHIVE)
qe_ret 
qelog_set_archive(char *dir, char *name, char *exntension, 
	int num_roll, qe_size max_size, qe_size cmp_size);
#endif

void 
qelog_set_default_output(qelog_output_t func);

void 
qelog_set_handler(const char *name, qelog_level_e level,
	qelog_handler_t hanlder);

void 
qelog_domain_set_level(qe_const_str name, qelog_level_e level);

void 
qelog_domain_set_handler(qe_const_str name, qelog_handler_t handler);

void 
qelog_domain_set_output(qe_const_str name, qelog_output_t output);

void
qelog_domain_show(void);

void 
qelog_set_output_enable(qe_bool en);

void 
qelog_show_summary(void);

void qelog_hexdump(const char *name, qe_u8 level, const char *file, const char *func, int linenr, 
    const void *vbuf, unsigned int len);
void qelog_bitdump(const char *name, qe_u8 level, const char *file, const char *func, int linenr, 
	const void *vbuf, qe_size len);

#define QELOG_DOMAIN(domain)	static const char *__log_domain = domain;

#define qe_debug(...)				qelog(__log_domain, QELOG_DEBUG, 	__FILE__, __func__, __LINE__, __VA_ARGS__)
#define qe_info(...)	 			qelog(__log_domain, QELOG_INFO, 	__FILE__, __func__, __LINE__, __VA_ARGS__)
#define qe_notice(...)				qelog(__log_domain, QELOG_NOTICE, 	__FILE__, __func__, __LINE__, __VA_ARGS__)
#define qe_warning(...) 			qelog(__log_domain, QELOG_WARNING, 	__FILE__, __func__, __LINE__, __VA_ARGS__)
#define qe_critical(...)			qelog(__log_domain, QELOG_CRITICAL, __FILE__, __func__, __LINE__, __VA_ARGS__)
#define qe_error(...)	 			qelog(__log_domain, QELOG_ERROR, 	__FILE__, __func__, __LINE__, __VA_ARGS__)
#define qe_fatal(...)				qelog(__log_domain, QELOG_FATAL, 	__FILE__, __func__, __LINE__, __VA_ARGS__)

#define qe_hexdump_debug(...)		qelog_hexdump(__log_domain, QELOG_DEBUG,	__FILE__, __func__, __LINE__, __VA_ARGS__)
#define qe_hexdump_info(...)		qelog_hexdump(__log_domain, QELOG_INFO, 	__FILE__, __func__, __LINE__, __VA_ARGS__)
#define qe_hexdump_notice(...)		qelog_hexdump(__log_domain, QELOG_NOTICE, 	__FILE__, __func__, __LINE__, __VA_ARGS__)
#define qe_hexdump_warning(...)		qelog_hexdump(__log_domain, QELOG_WARNING, __FILE__, __func__, __LINE__, __VA_ARGS__)

#define qe_bitdump_debug(...)		qelog_bitdump(__log_domain, QELOG_DEBUG,		__FILE__, __func__, __LINE__, __VA_ARGS__)
#define qe_bitdump_info(...)		qelog_bitdump(__log_domain, QELOG_INFO, 		__FILE__, __func__, __LINE__, __VA_ARGS__)
#define qe_bitdump_notice(...)		qelog_bitdump(__log_domain, QELOG_NOTICE, 		__FILE__, __func__, __LINE__, __VA_ARGS__)
#define qe_bitdump_warning(...)		qelog_bitdump(__log_domain, QELOG_WARNING, 	__FILE__, __func__, __LINE__, __VA_ARGS__)

#define qelog_debug(name, ...)	 	qelog(name, QELOG_DEBUG, 	__FILE__, __func__, __LINE__, __VA_ARGS__)
#define qelog_info(name, ...)	 	qelog(name, QELOG_INFO, 	__FILE__, __func__, __LINE__, __VA_ARGS__)
#define qelog_notice(name, ...)	 	qelog(name, QELOG_NOTICE, 	__FILE__, __func__, __LINE__, __VA_ARGS__)
#define qelog_warning(name, ...) 	qelog(name, QELOG_WARNING, 	__FILE__, __func__, __LINE__, __VA_ARGS__)
#define qelog_critical(name, ...)	qelog(name, QELOG_CRITICAL, __FILE__, __func__, __LINE__, __VA_ARGS__)
#define qelog_error(name, ...)	 	qelog(name, QELOG_ERROR, 	__FILE__, __func__, __LINE__, __VA_ARGS__)
#define qelog_fatal(name, ...)		qelog(name, QELOG_FATAL, 	__FILE__, __func__, __LINE__, __VA_ARGS__)

#define qehex_debug(name, ...)		qelog_hexdump(name, QELOG_DEBUG,  	__FILE__, __func__, __LINE__, __VA_ARGS__)
#define qehex_info(name, ...)		qelog_hexdump(name, QELOG_INFO,	__FILE__, __func__, __LINE__, __VA_ARGS__)
#define qehex_notice(name, ...)		qelog_hexdump(name, QELOG_NOTICE,	__FILE__, __func__, __LINE__, __VA_ARGS__)
#define qehex_warning(name, ...)	qelog_hexdump(name, QELOG_WARNING,	__FILE__, __func__, __LINE__, __VA_ARGS__)

#define qebit_debug(name, ...)		qelog_bitdump(name, QELOG_DEBUG,  	__FILE__, __func__, __LINE__, __VA_ARGS__)
#define qebit_info(name, ...)		qelog_bitdump(name, QELOG_INFO,	__FILE__, __func__, __LINE__, __VA_ARGS__)
#define qebit_notice(name, ...)		qelog_bitdump(name, QELOG_NOTICE,	__FILE__, __func__, __LINE__, __VA_ARGS__)
#define qebit_warning(name, ...)	qelog_bitdump(name, QELOG_WARNING,	__FILE__, __func__, __LINE__, __VA_ARGS__)

#define SYS_LOGDOMAIN  		"sys"
#define sys_debug(...)  	qelog_debug(SYS_LOGDOMAIN, __VA_ARGS__)
#define sys_info(...)   	qelog_info(SYS_LOGDOMAIN, __VA_ARGS__)
#define sys_notice(...) 	qelog_notice(SYS_LOGDOMAIN, __VA_ARGS__)
#define sys_warning(...)   	qelog_warning(SYS_LOGDOMAIN, __VA_ARGS__)
#define sys_critical(...)   qelog_critical(SYS_LOGDOMAIN, __VA_ARGS__)
#define sys_error(...)  	qelog_error(SYS_LOGDOMAIN, __VA_ARGS__)
#define sys_fatal(...)		qelog_fatal(SYS_LOGDOMAIN, __VA_ARGS__)



#endif /* __QE_LOG_H__ */

